<?php
/**
 *      [Discuz!] (C)2001-2099 Comsenz Inc.
 *      This is NOT a freeware, use is subject to license terms
 *
 *      $Id: dzf_lib_mcrypt.php 338 2013-04-27 08:06:38Z laoguozhang $
 */

if(!defined('IN_DISCUZ')) {
	exit('Access Denied');
}

/**
 * 调用 php 自带的 mcrypt 相关方法进行加密解密
 */
class dzf_lib_mcrypt  extends dzf_base_model {

    /**
     * 加密算法
     */
    private static $_cipher = MCRYPT_RIJNDAEL_256;

    /**
     * 算法块大小
     */
    private static $_block = 64;

    /**
     * 算法模式
     */
    private static $_mode = MCRYPT_MODE_CBC;

    /**
     * encrypt
     * 加密
     *
     * @param  string $string 要加密的字符串
     * @param  string $key 密钥
     * @return string
     */
    public function encrypt($string, $key) {
        $string = $this->pad($string);
        $iv = mcrypt_create_iv($this->getIVSize(), $this->getRandom());
        $string = mcrypt_encrypt(self::$_cipher, $key, $string, self::$_mode, $iv);

        return base64_encode($iv . $string);
    }

    /**
     * decrypt
     * 解密
     *
     * @param  string $string 要加密的字符串
     * @param  string $key 密钥
     * @return string
     */
    public function decrypt($string, $key) {
        $string = base64_decode($string);
        $iv = substr($string, 0, $this->getIVSize());

        $string = substr($string, $this->getIVSize());
        $string = mcrypt_decrypt(self::$_cipher, $key, $string, self::$_mode, $iv);

        return $this->unpad($string);
    }


    /**
     * 根据算法和模式计算需要的矢量长度
     *
     * @returns
     */
    public function getIVSize() {
        return mcrypt_get_iv_size(self::$_cipher, self::$_mode);
    }

    /**
     * 生成随机数，默认从系统的 /dev/urandom 目录取
     *
     * @returns
     */
    public function getRandom() {
        if (defined('MCRYPT_DEV_URANDOM')) {
            return MCRYPT_DEV_URANDOM;
        } elseif (defined('MCRYPT_DEV_RANDOM')) {
            return MCRYPT_DEV_RANDOM;
        } else {
            mt_srand();
            return MCRYPT_RAND;
        }
    }

    /**
     * 根据算法块大小处理字符串，为了验证字符串长度是否改变
     *
     * @param $string
     *
     * @returns
     */
    public function pad($string) {
        $pad = self::$_block - (strlen($string) % self::$_block);
        // 补充字符至block大小倍数
        return $string .= str_repeat(chr($pad), $pad);
    }

    /**
     * 过滤填充字符
     *
     * @param $string
     *
     * @returns
     */
    public function unpad($string) {
        $length = strlen($string);
        // 取最后一位，是补充的长度的数
        $pad = ord($string[$length - 1]);
        // pad 的值有效
        if ($pad && $pad <= self::$_block) {
            // 按照补充的字符截去多余字符
            return substr($string, 0, $length - $pad);
        }
    }
}
